package org.jeecg.modules.friends.user.service.impl;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.friends.auth.dto.AuthDetailInfo;
import org.jeecg.modules.friends.auth.dto.AuthInfo;
import org.jeecg.modules.friends.auth.dto.UserExtDTO;
import org.jeecg.modules.friends.auth.entity.UserAuthentication;
import org.jeecg.modules.friends.auth.service.IUserAuthenticationService;
import org.jeecg.modules.friends.auth.service.impl.UserAuthenticationServiceImpl;
import org.jeecg.modules.friends.dao.InvitedUserDAO;
import org.jeecg.modules.friends.dao.ReadyToDeleteDAO;
import org.jeecg.modules.friends.dao.SystemConfigDAO;
import org.jeecg.modules.friends.dao.UserPicsDAO;
import org.jeecg.modules.friends.enums.AuthStatusEnum;
import org.jeecg.modules.friends.enums.BaseInfoStatusEnum;
import org.jeecg.modules.friends.enums.FriendsStatusEnum;
import org.jeecg.modules.friends.enums.UserPicsStatusEnum;
import org.jeecg.modules.friends.enums.UserStatusEnum;
import org.jeecg.modules.friends.friendsinfo.dto.FriendsCountInfo;
import org.jeecg.modules.friends.friendsinfo.entity.FriendsInfo;
import org.jeecg.modules.friends.friendsinfo.service.IFriendsInfoService;
import org.jeecg.modules.friends.model.InvitedUserDO;
import org.jeecg.modules.friends.model.ReadyToDeleteDO;
import org.jeecg.modules.friends.model.SystemConfigDO;
import org.jeecg.modules.friends.model.UserPicsDO;
import org.jeecg.modules.friends.model.VipUserDO;
import org.jeecg.modules.friends.moments.entity.Moments;
import org.jeecg.modules.friends.moments.mapper.MomentsMapper;
import org.jeecg.modules.friends.moments.service.IMomentsService;
import org.jeecg.modules.friends.momentspics.entity.MomentsPics;
import org.jeecg.modules.friends.momentspics.service.IMomentsPicsService;
import org.jeecg.modules.friends.service.UserReportService;
import org.jeecg.modules.friends.service.VipUserService;
import org.jeecg.modules.friends.transfer.UserTransfer;
import org.jeecg.modules.friends.user.dto.AuthInfoDTO;
import org.jeecg.modules.friends.user.dto.DetailEditDTO;
import org.jeecg.modules.friends.user.dto.HomePageUserDTO;
import org.jeecg.modules.friends.user.dto.MomentPicDTO;
import org.jeecg.modules.friends.user.dto.SelfDetailInfoDTO;
import org.jeecg.modules.friends.user.dto.SysUserDTO;
import org.jeecg.modules.friends.user.dto.SysUserDetailDTO;
import org.jeecg.modules.friends.user.dto.UserDetailInfoDTO;
import org.jeecg.modules.friends.user.dto.UserPicDTO;
import org.jeecg.modules.friends.user.entity.User;
import org.jeecg.modules.friends.user.mapper.UserMapper;
import org.jeecg.modules.friends.user.param.UserParam;
import org.jeecg.modules.friends.user.param.FreezeOperateParam;
import org.jeecg.modules.friends.user.param.HomePageUserRequest;
import org.jeecg.modules.friends.user.param.OperateAuthInfoParam;
import org.jeecg.modules.friends.user.param.SelfDetailInfoEditParam;
import org.jeecg.modules.friends.user.param.UserAuthDetailParam;
import org.jeecg.modules.friends.user.param.UserEditParam;
import org.jeecg.modules.friends.user.param.UserPageParam;
import org.jeecg.modules.friends.user.service.IUserService;
import org.jeecg.modules.friends.utils.ImageUtils;
import org.jeecg.modules.friends.utils.NearbyUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserPicsDAO userPicsDAO;

    @Autowired
    private MomentsMapper momentsMapper;

    @Autowired
    private IMomentsPicsService momentsPicsService;

    @Autowired
    private IUserAuthenticationService userAuthenticationService;

    @Autowired
    private IFriendsInfoService friendsInfoService;

    @Autowired
    private VipUserService vipUserService;

    @Autowired
    private InvitedUserDAO invitedUserDAO;

    @Autowired
    private UserReportService userReportService;

    @Autowired
    private SystemConfigDAO systemConfigDAO;

    @Autowired
    private ReadyToDeleteDAO readyToDeleteDAO;

    @Autowired
    private IMomentsService momentsService;

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public User getUserByPhone(String phone) {
        LambdaQueryWrapper<User> query = new LambdaQueryWrapper<User>();
        query.eq(User::getMobile, phone);
        userMapper.selectOne(query);
        return userMapper.selectOne(query);
    }

    @Override
    @Transactional
    public User registerUser(String phone, String inviteUserId) {
        Random random = new Random();
        User user = new User();
        user.setMobile(phone);
        user.setAddTime(new Date());
        user.setUpdateTime(new Date());
        user.setNickname("用户" + random.nextInt(1000));
        user.setHeadPicUrl(
                "https://friends-images.oss-cn-hangzhou.aliyuncs"
                        + ".com/images/fbbc67c9-80a4-4a1f-b7e9-a304edf30b64/红蓝_1721450328376.png");
        userMapper.insert(user);
        if (StringUtils.isNotEmpty(inviteUserId)) {
            Long userId = Long.valueOf(inviteUserId);
            InvitedUserDO invitedUserDO = new InvitedUserDO();
            invitedUserDO.setInvitedUserId(user.getId());
            invitedUserDO.setUserId(userId);
            invitedUserDO.setMobile(user.getMobile());
            invitedUserDO.setAddTime(new Date());
            invitedUserDO.setUpdateTime(new Date());
            invitedUserDAO.insert(invitedUserDO);
        }
        return user;
    }

    @Override
    public int updateUserInfo(UserEditParam param, User user) {
        user.setNickname(param.getNickName());
        user.setGender(param.getGender());
        user.setBirthday(param.getBirthday());
        user.setConstellation(param.getConstellation());
        user.setHeight(param.getHeight());
        user.setWeight(param.getWeight());
        user.setCurrentResidence(param.getCurrentResidence());
        user.setHometown(param.getHometown());
        user.setMaritalStatus(param.getMaritalStatus());
        user.setEducation(param.getEducation());
        user.setUpdateTime(new Date());
        user.setWechat(param.getWechat());
        return userMapper.updateById(user);
    }

    @Override
    public void updateSelfDescription(String selfDescription, User user) {
        user.setSelfDescription(selfDescription);
        user.setUpdateTime(new Date());
        userMapper.updateById(user);
    }

    @Override
    public void updateFamilyDescription(String familyDescription, User user) {
        user.setFamilyDescription(familyDescription);
        user.setUpdateTime(new Date());
        userMapper.updateById(user);
    }

    @Override
    public void updateFullInfo(String lifePartnerRequirements, String familyDescription, String hobbies,
            String nickName, User user) {
        user.setLifePartnerRequirements(lifePartnerRequirements);
        user.setFamilyDescription(familyDescription);
        user.setHobbies(hobbies);
        user.setNickname(nickName);
        user.setIsFillInfoRewards(1);
        user.setUpdateTime(new Date());
        userMapper.updateById(user);
        vipUserService.addVipUser(user, 1, 7, 3 * 24 * 3600L * 1000);
    }

    @Override
    public void updateHobbies(String hobbies, User user) {
        user.setHobbies(hobbies);
        user.setUpdateTime(new Date());
        userMapper.updateById(user);
    }

    @Override
    @Transactional
    public void updateUserPics(List<UserPicDTO> userPicDTOList, User user) {
        List<UserPicsDO> userPicsDOS = userPicsDAO.queryByUserId(user.getId());
        if (CollectionUtils.isNotEmpty(userPicsDOS)) {
            userPicsDAO.deleteByUserId(user.getId());
        }
        userPicsDAO.insertBatch(userPicDTOList.stream().map(userPicDTO -> convertToPics(userPicDTO, user.getId()))
                .collect(Collectors.toList()));
    }

    @Override
    public HomePageUserDTO recommendUser(HomePageUserRequest request, User user) {
        User select = null;
        if (Objects.nonNull(request.getUserId()) && request.getUserId() > 0) {
            select = userMapper.selectById(request.getUserId());
        }
        if (Objects.isNull(select)) {
            LambdaQueryWrapper<User> userLambdaQueryWrapper = wrapQuery(request);
            List<Long> passedIds = Lists.newArrayList();
            if (Objects.nonNull(user)) {
                userLambdaQueryWrapper.eq(User::getCurrentResidence, user.getCurrentResidence());
                List<FriendsInfo> passed = friendsInfoService.queryPassedList(user.getId());
                if (CollectionUtils.isNotEmpty(passed)) {
                    passedIds = passed.stream().map(FriendsInfo::getToUserId).collect(Collectors.toList());
                }
                if (StringUtils.isEmpty(request.getGender()) && StringUtils.isNotEmpty(user.getGender())) {
                    if (user.getGender().equals("男")) {
                        userLambdaQueryWrapper.eq(User::getGender, "女");
                    } else {
                        userLambdaQueryWrapper.eq(User::getGender, "男");
                    }
                }
                passedIds.add(user.getId());
                userLambdaQueryWrapper.notIn(User::getId, passedIds);
            }

            List<User> userList = userMapper.selectList(userLambdaQueryWrapper);

            if (CollectionUtils.isEmpty(userList) && (Objects.isNull(request.getCityType()) || user == null)) {
                userLambdaQueryWrapper.clear();
                userLambdaQueryWrapper = wrapQuery(request);
                if (user != null) {
                    if (StringUtils.isEmpty(request.getGender()) && StringUtils.isNotEmpty(user.getGender())) {
                        if (user.getGender().equals("男")) {
                            userLambdaQueryWrapper.eq(User::getGender, "女");
                        } else {
                            userLambdaQueryWrapper.eq(User::getGender, "男");
                        }
                    }
                }
                if (CollectionUtils.isNotEmpty(passedIds)) {
                    userLambdaQueryWrapper.notIn(User::getId, passedIds);
                }
                userList = userMapper.selectList(userLambdaQueryWrapper);
            }
            if (CollectionUtils.isEmpty(userList)) {
                return null;
            }
            select = userList.get(0);
        }

        HomePageUserDTO homePageUserDTO =
                wrapHomePageDTO(select, user, false, request.getLatitude(), request.getLongitude());
        return homePageUserDTO;
    }

    private HomePageUserDTO wrapHomePageDTO(User userSelect, User selfUser, Boolean friend, String latitude,
            String longitude) {
        HomePageUserDTO homePageUserDTO = new HomePageUserDTO();
        BeanUtils.copyProperties(userSelect, homePageUserDTO);
        homePageUserDTO.setUserId(userSelect.getId());

        if (selfUser != null) {
            if (StringUtils.isNotEmpty(selfUser.getLat()) && StringUtils.isNotEmpty(selfUser.getLng())) {
                if (StringUtils.isNotEmpty(userSelect.getLat()) && StringUtils.isNotEmpty(userSelect.getLat())) {
                    Double distance = NearbyUtils
                            .calculateDistance(selfUser.getLat(), selfUser.getLng(), userSelect.getLat(),
                                    userSelect.getLng());
                    homePageUserDTO.setDistance(distance + "千米");
                }
            }
            List<FriendsInfo> friendsInfoList =
                    friendsInfoService.queryByFromUserIdAndToUserId(selfUser.getId(), userSelect.getId());
            if (CollectionUtils.isNotEmpty(friendsInfoList)) {
                FriendsInfo friendsInfo =
                        friendsInfoList.stream().filter(x -> x.getStatus() == FriendsStatusEnum.FRIEND.getCode())
                                .findFirst().orElse(null);
                if (friendsInfo == null) {
                    homePageUserDTO.setWechat("***");
                } else {
                    homePageUserDTO.setWechat(userSelect.getWechat());
                    homePageUserDTO.setApplyRestrict(true);
                }
            } else {
                homePageUserDTO.setWechat("***");
            }
        } else {
            homePageUserDTO.setWechat("***");
        }
        if (StringUtils.isNotEmpty(userSelect.getLat()) && StringUtils.isNotEmpty(userSelect.getLat())) {
            if (StringUtils.isNotEmpty(latitude) && StringUtils.isNotEmpty(longitude)) {
                Double distance =
                        NearbyUtils.calculateDistance(latitude, longitude, userSelect.getLat(), userSelect.getLng());
                homePageUserDTO.setDistance(distance + "千米");
            }
        }
        homePageUserDTO.setNickName(userSelect.getNickname());
        homePageUserDTO.setCurrentResidence(userSelect.getCurrentResidence());
        homePageUserDTO.setGender(userSelect.getGender());
        List<UserPicsDO> userPicsDOS = userPicsDAO.queryByUserId(userSelect.getId());
        if (CollectionUtils.isNotEmpty(userPicsDOS)) {
            homePageUserDTO.setUserPicUrls(
                    userPicsDOS.stream().map(userPicsDO -> convertToPicsDTO(userPicsDO)).collect(Collectors.toList()));
        }
        if (Objects.nonNull(selfUser)) {
            homePageUserDTO.setHasFamilyDescription(StringUtils.isNotEmpty(selfUser.getFamilyDescription()));
            homePageUserDTO.setHasSelfDescription(StringUtils.isNotEmpty(selfUser.getSelfDescription()));
            homePageUserDTO.setHasHobbiesDescription(StringUtils.isNotEmpty(selfUser.getHobbies()));
            homePageUserDTO
                    .setHasLifePartnerRequirements(StringUtils.isNotEmpty(selfUser.getLifePartnerRequirements()));
            VipUserDO vipUserDO = vipUserService.findByUserId(selfUser.getId());
            if (Objects.nonNull(vipUserDO)) {
                homePageUserDTO.setTicketLeft(vipUserDO.getTicketLeft());
            }
        }
        LambdaQueryWrapper<Moments> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Moments::getUserId, userSelect.getId());
        lambdaQueryWrapper.orderByDesc(Moments::getId);
        List<Moments> moments = momentsMapper.selectList(lambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(moments)) {
            Moments first = moments.get(0);

            List<Long> momentIds = moments.stream()
                    .map(Moments::getId).collect(Collectors.toList());

            List<MomentsPics> momentsPicsList = momentsPicsService.selectByMomentsIds(momentIds);

            if (CollectionUtils.isNotEmpty(momentsPicsList)) {
                momentsPicsList = momentsPicsList.subList(0, Math.min(momentsPicsList.size(), 3));
                homePageUserDTO.setMomentsPics(
                        momentsPicsList.stream().map(momentsPic -> convertToMomentsPicDTO(momentsPic))
                                .collect(Collectors.toList()));
            }
        }
        List<UserAuthentication> userAuthentications = userAuthenticationService.selectByUserId(userSelect.getId());
        if (CollectionUtils.isNotEmpty(userAuthentications)) {
            homePageUserDTO.setUserAuthentications(
                    userAuthentications.stream().map(userAuthentication -> UserTransfer.convertToUserAuthenticationDTO(
                            userAuthentication)).collect(Collectors.toList()));
        }

        homePageUserDTO.setLifePartnerRequirements(userSelect.getLifePartnerRequirements());
        return homePageUserDTO;
    }

    @Override
    public UserDetailInfoDTO getUserDetailInfo(User user) {
        UserDetailInfoDTO userDetailInfoDTO = new UserDetailInfoDTO();
        userDetailInfoDTO.setUserId(user.getId());
        userDetailInfoDTO.setRecommended(user.getRecommended());
        userDetailInfoDTO.setHeadPicUrl(user.getHeadPicUrl());
        userDetailInfoDTO.setAssociator(false);
        userDetailInfoDTO.setNickName(user.getNickname());
        FriendsCountInfo friendsCountInfo = friendsInfoService.queryFriendsCountInfo(user.getId());
        userDetailInfoDTO.setFansCount(friendsCountInfo.getFansCount());
        userDetailInfoDTO.setFollowersCount(friendsCountInfo.getFollowsCount());
        userDetailInfoDTO.setFriendsCount(friendsCountInfo.getFriendsCount());
        userDetailInfoDTO.setUnreadCount(friendsCountInfo.getFansUnreadCount());
        userDetailInfoDTO.setRecentVisitsCount(0L);
        userDetailInfoDTO.setBaseInfoStatus(
                user.getBaseInfoStatus() == null ? BaseInfoStatusEnum.default_success.getCode()
                                                 : user.getBaseInfoStatus());
        userDetailInfoDTO.setBaseInfoPassedReason(user.getBaseInfoFailReason());
        VipUserDO vipUserDO = vipUserService.findByUserId(user.getId());
        if (!Objects.isNull(vipUserDO)) {
            userDetailInfoDTO.setAssociator(vipUserDO.getVipEndDate() > System.currentTimeMillis());
            userDetailInfoDTO.setPeriodValidity(sdf.format(vipUserDO.getVipEndDate()));
        } else {
            userDetailInfoDTO.setAssociator(false);
        }
        try {
            // 已经领取过，则不需要完善
            if (user.getIsFillInfoRewards() != null && user.getIsFillInfoRewards() == 1) {
                userDetailInfoDTO.setFillVipInfoFlag(false);
            } else {
                // 有一项为空的，则需要完善
                if (StringUtils.isAnyEmpty(user.getNickname(), user.getSelfDescription(), user.getHobbies(),
                        user.getLifePartnerRequirements())) {
                    userDetailInfoDTO.setFillVipInfoFlag(true);
                } else {
                    userDetailInfoDTO.setFillVipInfoFlag(false);
                }
            }
        } catch (Exception e) {
            log.error("getUserDetailInfo error.", e);
        }
        return userDetailInfoDTO;
    }

    @Override
    public User findById(Long toUserId) {
        return userMapper.selectById(toUserId);
    }

    @Override
    public void updateLifePartnerRequirements(String lifePartnerRequirements, User user) {
        user.setLifePartnerRequirements(lifePartnerRequirements);
        user.setUpdateTime(new Date());
        userMapper.updateById(user);
    }

    @Override
    public DetailEditDTO getDetailEditDTO(User user) {
        User userDB = getById(user.getId());
        if (!Objects.isNull(userDB)) {
            DetailEditDTO detailEditDTO = new DetailEditDTO();
            BeanUtils.copyProperties(userDB, detailEditDTO);
            detailEditDTO.setNickName(userDB.getNickname());
            return detailEditDTO;
        }
        return null;
    }

    @Override
    public SelfDetailInfoDTO getSelfDetailInfo(User user) {
        User userDB = getById(user.getId());
        if (!Objects.isNull(userDB)) {
            SelfDetailInfoDTO detailEditDTO = new SelfDetailInfoDTO();
            detailEditDTO.setSelfDescription(userDB.getSelfDescription());
            detailEditDTO.setFamilyDescription(userDB.getFamilyDescription());
            detailEditDTO.setHobbies(userDB.getHobbies());
            detailEditDTO.setLifePartnerRequirements(userDB.getLifePartnerRequirements());
            List<UserPicsDO> userPicsDOS = userPicsDAO.queryByUserId(userDB.getId());
            if (CollectionUtils.isNotEmpty(userPicsDOS)) {
                List<UserPicDTO> userPicDTOS =
                        userPicsDOS.stream().map(this::convertToPicsDTO).collect(Collectors.toList());
                detailEditDTO.setUserPicDTOList(userPicDTOS);
            }
            return detailEditDTO;
        }
        return null;
    }

    @Override
    public HomePageUserDTO getDetailInfo(User user, Long userId) {
        User selectUser = userMapper.selectById(userId);
        if (!Objects.isNull(selectUser)) {
            return wrapHomePageDTO(selectUser, user, true, null, null);
        }
        return null;
    }

    @Override
    public void updateSelfDetailInfo(SelfDetailInfoEditParam request, User user) {
        if (CollectionUtils.isNotEmpty(request.getUserPicDTOList())) {
            List<UserPicsDO> userPicsDOS = userPicsDAO.queryByUserId(user.getId());
            if (CollectionUtils.isNotEmpty(userPicsDOS)) {
                userPicsDAO.deleteByUserId(user.getId());
            }
            userPicsDAO.insertBatch(
                    request.getUserPicDTOList().stream().map(userPicDTO -> convertToPics(userPicDTO, user.getId()))
                            .collect(Collectors.toList()));
        }
        User userDb = getById(user.getId());
        if (Objects.isNull(userDb)) {
            return;
        }
        userDb.setSelfDescription(request.getSelfDescription());
        userDb.setFamilyDescription(request.getFamilyDescription());
        userDb.setHobbies(request.getHobbyDescription());
        userDb.setLifePartnerRequirements(request.getLifePartnerRequirements());
        userMapper.updateById(userDb);
    }

    @Override
    public void updateLocation(User user, String lat, String lng) {
        User userDb = getById(user.getId());
        if (Objects.isNull(userDb)) {
            return;
        }
        userDb.setLat(lat);
        userDb.setLng(lng);
        userMapper.updateById(userDb);
    }

    @Override
    public void updateRecommendStatus(User user, boolean b) {
        User userDb = getById(user.getId());
        if (Objects.isNull(userDb)) {
            return;
        }
        userDb.setRecommended(b);
        userMapper.updateById(userDb);
    }

    @Override
    public void userLogoff(User user, int type) {
        SystemConfigDO systemConfigDO = systemConfigDAO.findOne();
        User userDb = getById(user.getId());
        if (Objects.isNull(userDb)) {
            return;
        }
        readyToDeleteDAO.deleteByUserId(user.getId());
        Long expireTime = System.currentTimeMillis();
        if (type == 0) {
            expireTime = systemConfigDO == null ? System.currentTimeMillis() + 5000
                                                : System.currentTimeMillis() + systemConfigDO.getSystemReadyToDelete();
        }
        if (type == 1) {
            expireTime = systemConfigDO == null ? System.currentTimeMillis() + 15 * 3600 * 24 * 1000
                                                : System.currentTimeMillis() + systemConfigDO.getReadyToDelete();
        }
        ReadyToDeleteDO deleteDO = new ReadyToDeleteDO();
        deleteDO.setUserId(user.getId());
        deleteDO.setAddTime(new Date());
        deleteDO.setExpireTime(expireTime);
        deleteDO.setUpdateTime(new Date());
        deleteDO.setStatus(1);
        readyToDeleteDAO.insert(deleteDO);
    }

    @Override
    public Page<SysUserDTO> userPageList(UserPageParam request) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(request.getMobile())) {
            lambdaQueryWrapper.eq(User::getMobile, request.getMobile());
        }
        if (StringUtils.isNotEmpty(request.getNickName())) {
            lambdaQueryWrapper.eq(User::getNickname, request.getNickName());
        }
        if (Objects.nonNull(request.getId())) {
            lambdaQueryWrapper.eq(User::getId, request.getId());
        }
        if (Objects.nonNull(request.getAuthStatus())) {
            lambdaQueryWrapper.eq(User::getAuthStatusV2, request.getAuthStatus());
        }
        if (StringUtils.isNotEmpty(request.getGender())) {
            lambdaQueryWrapper.eq(User::getGender, request.getGender());
        }
        if (request.getBaseInfoStatus() != null) {
            Integer baseInfoStatus = request.getBaseInfoStatus();
            if (BaseInfoStatusEnum.auditing.getCode().equals(baseInfoStatus)) {
                lambdaQueryWrapper.in(User::getBaseInfoStatus, BaseInfoStatusEnum.default_success.getCode(),
                        BaseInfoStatusEnum.auditing.getCode());
                lambdaQueryWrapper.eq(User::getAuthStatusV2, AuthStatusEnum.PASSED.getCode());
            } else {
                lambdaQueryWrapper.eq(User::getBaseInfoStatus, request.getBaseInfoStatus());
            }

        }
        lambdaQueryWrapper.orderByDesc(User::getId);
        Page<User> userPage =
                userMapper.selectPage(new Page<>(request.getPageNo(), request.getPageSize()), lambdaQueryWrapper);
        if (Objects.nonNull(userPage) && userPage.getRecords() != null) {
            Set<Long> userIdSet = userPage.getRecords().stream().map(User::getId).collect(Collectors.toSet());
            List<UserAuthentication> userAuthentications = userAuthenticationService.selectByUserIdSet(userIdSet);
            Map<Long, List<UserAuthentication>> authInfoMap = Maps.newHashMap();
            if (CollectionUtils.isNotEmpty(userAuthentications)) {
                authInfoMap =
                        userAuthentications.stream().collect(Collectors.groupingBy(UserAuthentication::getUserId));
            }
            Map<Long, List<UserAuthentication>> finalAuthInfoMap = authInfoMap;
            List<SysUserDTO> sysUserDTOS =
                    userPage.getRecords().stream().map((x) -> {
                        return convertToSysUserDTO(x, finalAuthInfoMap);
                    })
                            .collect(Collectors.toList());
            Page<SysUserDTO> page = new Page<>(request.getPageNo(), request.getPageSize(), userPage.getTotal());
            page.setRecords(sysUserDTOS);
            return page;
        }
        return new Page<>(request.getPageNo(), request.getPageSize(), 0L);
    }

    public Page<HomePageUserDTO> userPageListDetail(UserPageParam request, User currentUser) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(request.getMobile())) {
            lambdaQueryWrapper.eq(User::getMobile, request.getMobile());
        }
        if (StringUtils.isNotEmpty(request.getNickName())) {
            lambdaQueryWrapper.eq(User::getMobile, request.getNickName());
        }
        if (Objects.nonNull(request.getId())) {
            lambdaQueryWrapper.eq(User::getId, request.getId());
        }
        if (Objects.nonNull(request.getAuthStatus())) {
            lambdaQueryWrapper.eq(User::getAuthStatusV2, request.getAuthStatus());
        }
        if (StringUtils.isNotEmpty(request.getGender())) {
            lambdaQueryWrapper.eq(User::getGender, request.getGender());
        }
        lambdaQueryWrapper.orderByDesc(User::getId);
        Page<User> userPage =
                userMapper.selectPage(new Page<>(request.getPageNo(), request.getPageSize()), lambdaQueryWrapper);
        if (Objects.nonNull(userPage) && userPage.getRecords() != null) {
            Set<Long> userIdSet = userPage.getRecords().stream().map(User::getId).collect(Collectors.toSet());
            List<HomePageUserDTO> sysUserDTOS =
                    userPage.getRecords().stream().map((userSelect) -> {
                        return wrapHomePageDTO(userSelect, currentUser, false, "", "");
                    })
                            .collect(Collectors.toList());
            Page<HomePageUserDTO> page = new Page<>(request.getPageNo(), request.getPageSize(), userPage.getTotal());
            page.setRecords(sysUserDTOS);
            return page;
        }
        return new Page<>(request.getPageNo(), request.getPageSize(), 0L);
    }

    @Override
    public SysUserDetailDTO userAuditDetail(UserAuthDetailParam request) {
        User userDB = getById(request.getUserId());
        if (!Objects.isNull(userDB)) {
            SysUserDetailDTO detailEditDTO = new SysUserDetailDTO();
            BeanUtils.copyProperties(userDB, detailEditDTO);
            detailEditDTO.setNickName(userDB.getNickname());
            detailEditDTO.setBaseInfoStatus(userDB.getBaseInfoStatus());
            detailEditDTO.setBaseInfoStatusDesc(BaseInfoStatusEnum.getByCode(userDB.getBaseInfoStatus()).getDesc());
            detailEditDTO.setBaseInfoFailReason(userDB.getBaseInfoFailReason());
            detailEditDTO.setLifePartnerRequirements(userDB.getLifePartnerRequirements());
            AuthDetailInfo authDetailInfo = userAuthenticationService.queryAuthDetailInfo(userDB);
            detailEditDTO.setJobAuthInfo(authDetailInfo.getJobAuthInfo());
            detailEditDTO.setIdCardAuthInfo(authDetailInfo.getIdCardAuthInfo());
            detailEditDTO.setEducationAuthInfo(authDetailInfo.getEducationAuthInfo());
            detailEditDTO.setUserPicList(userPicsDAO.queryByUserId(request.getUserId()));
            return detailEditDTO;
        }
        return new SysUserDetailDTO();
    }

    @Override
    public void operateUser(FreezeOperateParam param) {
        User user = getById(param.getUserId());
        if (Objects.isNull(user)) {
            return;
        }
        if (param.getOperateType() == 1) {
            user.setStatus(UserStatusEnum.FREEZE.getCode());
        }
        //发送短信冻结
        if (param.getOperateType() == 2) {
            user.setStatus(UserStatusEnum.NORMAL.getCode());
        }
        userMapper.updateById(user);
    }

    @Override
    public void operateAuthInfo(OperateAuthInfoParam param) {
        userAuthenticationService.operateAuthInfo(param);
    }

    @Override
    public void cancelUser(UserParam param) {
        User user = findById(param.getUserId());
        if (user == null) {
            return;
        }
        log.info("editInfo user {} , req {} ", JSON.toJSONString(user), JSON.toJSONString(param));
        userLogoff(user, 0);
    }

    @Override
    public void closeShowUrl(User user) {
        User userDb = getById(user.getId());
        if (Objects.isNull(userDb)) {
            return;
        }
        UserExtDTO userExtDTO = JSONObject.parseObject(user.getExtData(), UserExtDTO.class);
        if (userExtDTO != null) {
            userExtDTO.setShowInviteUrl(false);
            user.setExtData(JSONObject.toJSONString(userExtDTO));
            userMapper.updateById(user);
        }
    }

    @Override
    public void updateBaseInfoStatus(long userId, BaseInfoStatusEnum baseInfoStatusEnum, String failReason) {
        if (baseInfoStatusEnum == null) {
            return;
        }
        User userDb = getById(userId);
        if (Objects.isNull(userDb)) {
            return;
        }
        User update = new User();
        update.setId(userDb.getId());
        update.setBaseInfoStatus(baseInfoStatusEnum.getCode());
        if (StringUtils.isNotEmpty(failReason)) {
            update.setBaseInfoFailReason(failReason);
        }
        userMapper.updateById(update);
    }

    private UserPicDTO convertToPicsDTO(UserPicsDO userPicsDO) {
        UserPicDTO userPicDTO = new UserPicDTO();
        userPicDTO.setPicUrl(ImageUtils.compressImage(userPicsDO.getPicUrl()));
        userPicDTO.setOrder(userPicsDO.getOrderInfo());
        return userPicDTO;
    }

    private MomentPicDTO convertToMomentsPicDTO(MomentsPics momentsPics) {
        MomentPicDTO momentPicDTO = new MomentPicDTO();
        momentPicDTO.setPicUrl(ImageUtils.compressImage(momentsPics.getPicUrl()));
        momentPicDTO.setOrder(momentPicDTO.getOrder());
        return momentPicDTO;
    }

    private SysUserDTO convertToSysUserDTO(User user, Map<Long, List<UserAuthentication>> authInfoMap) {
        SysUserDTO sysUserDTO = new SysUserDTO();
        sysUserDTO.setCreateTime(user.getAddTime().getTime());
        sysUserDTO.setUpdateTime(user.getUpdateTime().getTime());
        sysUserDTO.setStatusCode(user.getStatus());
        sysUserDTO.setStatus(UserStatusEnum.of(user.getStatus()).getDesc());
        sysUserDTO.setMobile(user.getMobile());
        sysUserDTO.setWechat(user.getWechat());
        sysUserDTO.setHeadPicUrl(user.getHeadPicUrl());
        sysUserDTO.setNickName(user.getNickname());
        sysUserDTO.setUserId(user.getId());
        AuthInfo authInfo =
                UserAuthenticationServiceImpl.checkAuthInfoBackV2(authInfoMap.get(user.getId()), user, null);
        sysUserDTO.setAuthStatus(AuthStatusEnum.of(user.getAuthStatusV2()).getDesc());
        sysUserDTO.setBaseInfoStatusDesc(BaseInfoStatusEnum.getByCode(user.getBaseInfoStatus()).getDesc());
        return sysUserDTO;
    }

    private AuthInfoDTO convertToUserAuthenticationDTO(UserAuthentication userAuthentication) {
        AuthInfoDTO userAuthenticationDTO = new AuthInfoDTO();
        userAuthenticationDTO.setAuthStatus(userAuthentication.getAuthStatus());
        userAuthenticationDTO.setAuthType(userAuthentication.getAuthType());
        userAuthenticationDTO.setCompanyName(userAuthentication.getCompanyName());
        userAuthenticationDTO.setEducation(userAuthentication.getEducation());
        userAuthenticationDTO.setEducationType(userAuthentication.getEducationType());
        userAuthenticationDTO.setIdCardNo(encryptIdCardNo(userAuthentication.getIdCardNo()));
        userAuthenticationDTO.setJob(userAuthentication.getJob());
        if (StringUtils.isNotEmpty(userAuthentication.getRealName())) {
            userAuthenticationDTO.setRealName(userAuthentication.getRealName().substring(0, 1) + "**");
        }
        userAuthenticationDTO.setSchoolName(userAuthentication.getUniversity());
        userAuthenticationDTO.setIsStudent(userAuthentication.getIsStudent());
        return userAuthenticationDTO;
    }

    private String encryptIdCardNo(String idCardNo) {
        if (StringUtils.isEmpty(idCardNo)) {
            return idCardNo;
        }
        idCardNo = idCardNo.substring(0, 3) + "****";
        return idCardNo;
    }

    private LambdaQueryWrapper<User> wrapQuery(HomePageUserRequest request) {
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(request.getGender())) {
            userLambdaQueryWrapper.eq(User::getGender, request.getGender());
        }
        if (Objects.nonNull(request.getAgeMax()) && Objects.nonNull(request.getAgeMin()) && request.getAgeMin() > 0
                && request.getAgeMax() > 0) {
            Calendar calendarMin = Calendar.getInstance();
            calendarMin.add(Calendar.YEAR, -request.getAgeMax());
            String yearMin = sdf.format(calendarMin.getTime());

            Calendar calendarMax = Calendar.getInstance();
            calendarMax.add(Calendar.YEAR, -request.getAgeMin());
            String yearMax = sdf.format(calendarMax.getTime());
            userLambdaQueryWrapper.between(User::getBirthday, yearMin, yearMax);
        }
        if (Objects.nonNull(request.getEducationType())) {
            userLambdaQueryWrapper.ge(User::getEducationType, request.getEducationType());
        }
        if (Objects.nonNull(request.getHeightMax()) && Objects.nonNull(request.getHeightMin())
                && request.getHeightMin() > 0 && request.getHeightMax() > 0) {
            userLambdaQueryWrapper.between(User::getHeight, request.getHeightMin(), request.getHeightMax());
        }
        userLambdaQueryWrapper.ne(User::getRecommended, 0);
        userLambdaQueryWrapper.ne(User::getStatus, UserStatusEnum.CLOSING.getCode());
        userLambdaQueryWrapper.ne(User::getBaseInfoStatus, BaseInfoStatusEnum.audit_fail.getCode());
        userLambdaQueryWrapper.eq(User::getAuthStatus, AuthStatusEnum.PASSED.getCode());
        return userLambdaQueryWrapper;
    }


    private UserPicsDO convertToPics(UserPicDTO userPicDTO, Long userId) {
        UserPicsDO userPics = new UserPicsDO();
        userPics.setPicUrl(ImageUtils.getCorrectImageUrl(userPicDTO.getPicUrl()));
        userPics.setStatus(UserPicsStatusEnum.AVAILABLE.getCode());
        userPics.setUserId(userId);
        userPics.setOrderInfo(userPicDTO.getOrder());
        userPics.setAddTime(new Date());
        userPics.setUpdateTime(new Date());
        return userPics;
    }
}
